home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / yplot-0.000 / yplot-0 / yplot-0.9 / ps.c < prev    next >
C/C++ Source or Header  |  1996-06-04  |  16KB  |  627 lines

  1. /* $Id: ps.c,v 1.33 1995/03/11 20:27:13 mjl Exp $
  2.  * $Log: ps.c,v $
  3.  * Revision 1.33  1995/03/11  20:27:13  mjl
  4.  * All drivers: eliminated unnecessary variable initializations, other cleaning
  5.  * up.
  6.  *
  7.  * Revision 1.32  1995/01/10  09:37:00  mjl
  8.  * Fixed braindamage incurred last update.  Now switches to transparent
  9.  * background mode (no page fill) automatically if background color is white.
  10.  * Useful for including color EPSF files into TeX or whatever.
  11.  *
  12.  * Revision 1.31  1995/01/09  21:48:34  mjl
  13.  * Fixed background color fill to cover the entire page, including margin
  14.  * area.  
  15.  *
  16.  * Revision 1.30  1994/09/23  07:36:27  mjl
  17.  * Now generates ps files with the correct PLplot version number written.
  18.  *
  19.  * Revision 1.29  1994/09/01  22:28:09  mjl
  20.  * Fixed bug in current point update after state change.
  21.  *
  22.  * Revision 1.28  1994/08/27  03:40:32  mjl
  23.  * Fix to allow cmap1 color selections to appear in grayscale.  Contributed
  24.  * by Radey Shouman.
  25. */
  26.  
  27. /*    ps.c
  28.  
  29.     PLplot PostScript device driver.
  30. */
  31. #include "plDevs.h"
  32.  
  33. #ifdef PLD_ps
  34.  
  35. #include "plplotP.h"
  36. #include "drivers.h"
  37.  
  38. #include <string.h>
  39. #include <time.h>
  40.  
  41. /* Prototypes for functions in this file. */
  42.  
  43. static char  *ps_getdate    (void);
  44. static void  ps_init        (PLStream *);
  45. static void  fill_polygon    (PLStream *pls);
  46.  
  47. /* top level declarations */
  48.  
  49. #define LINELENGTH      78
  50. #define COPIES          1
  51. #define XSIZE           540        /* 7.5 x 10 [inches]    */
  52. #define YSIZE           720        /* (72 points = 1 inch) */
  53. #define ENLARGE         5
  54. #define XPSSIZE         ENLARGE*XSIZE
  55. #define YPSSIZE         ENLARGE*YSIZE
  56. #define XOFFSET         36        /* Margins --     */
  57. #define YOFFSET         36        /* .5 inches each */
  58. #define PSX             XPSSIZE-1
  59. #define PSY             YPSSIZE-1
  60. #define OF        pls->OutFile
  61. #define MIN_WIDTH    1        /* Minimum pen width */
  62. #define MAX_WIDTH    10        /* Maximum pen width */
  63. #define DEF_WIDTH    3        /* Default pen width */
  64.  
  65. /* These are for covering the page with the background color */
  66.  
  67. #define XMIN        -XOFFSET*ENLARGE
  68. #define XMAX        PSX+XOFFSET*ENLARGE
  69. #define YMIN        -XOFFSET*ENLARGE
  70. #define YMAX        PSY+XOFFSET*ENLARGE
  71.  
  72. /* Struct to hold device-specific info. */
  73.  
  74. typedef struct {
  75.     PLFLT pxlx, pxly;
  76.     PLINT xold, yold;
  77.  
  78.     PLINT xmin, xmax, xlen;
  79.     PLINT ymin, ymax, ylen;
  80.  
  81.     PLINT xmin_dev, xmax_dev, xlen_dev;
  82.     PLINT ymin_dev, ymax_dev, ylen_dev;
  83.  
  84.     PLFLT xscale_dev, yscale_dev;
  85.  
  86.     int llx, lly, urx, ury, ptcnt;
  87. } PSDev;
  88.  
  89. static char outbuf[128];
  90.  
  91. /*--------------------------------------------------------------------------*\
  92.  * plD_init_ps()
  93.  *
  94.  * Initialize device.
  95. \*--------------------------------------------------------------------------*/
  96.  
  97. void
  98. plD_init_psm(PLStream *pls)
  99. {
  100.     pls->color = 0;        /* Not a color device */
  101.     ps_init(pls);
  102. }
  103.  
  104. void
  105. plD_init_psc(PLStream *pls)
  106. {
  107.     pls->color = 1;        /* Is a color device */
  108.     ps_init(pls);
  109. }
  110.  
  111. static void
  112. ps_init(PLStream *pls)
  113. {
  114.     PSDev *dev;
  115.     float pxlx = YPSSIZE/LPAGE_X;
  116.     float pxly = XPSSIZE/LPAGE_Y;
  117.  
  118.     pls->family = 0;        /* Doesn't support familying for now */
  119.     pls->dev_fill0 = 1;        /* Can do solid fills */
  120.  
  121. /* Prompt for a file name if not already set */
  122.  
  123.     plOpenFile(pls);
  124.  
  125. /* Allocate and initialize device-specific data */
  126.  
  127.     if (pls->dev != NULL)
  128.     free((void *) pls->dev);
  129.  
  130.     pls->dev = calloc(1, (size_t) sizeof(PSDev));
  131.     if (pls->dev == NULL)
  132.     plexit("ps_init: Out of memory.");
  133.  
  134.     dev = (PSDev *) pls->dev;
  135.  
  136.     dev->xold = UNDEFINED;
  137.     dev->yold = UNDEFINED;
  138.  
  139.     plP_setpxl(pxlx, pxly);
  140.  
  141.     dev->llx = XPSSIZE;
  142.     dev->lly = YPSSIZE;
  143.     dev->urx = 0;
  144.     dev->ury = 0;
  145.     dev->ptcnt = 0;
  146.  
  147. /* Rotate by 90 degrees since portrait mode addressing is used */
  148.  
  149.     dev->xmin = 0;
  150.     dev->ymin = 0;
  151.     dev->xmax = PSX;
  152.     dev->ymax = PSY;
  153.     dev->xlen = dev->xmax - dev->xmin;
  154.     dev->ylen = dev->ymax - dev->ymin;
  155.  
  156.     plP_setphy(dev->xmin, dev->xmax, dev->ymin, dev->ymax);
  157.  
  158. /* Header comments into PostScript file */
  159.  
  160.     fprintf(OF, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  161.     fprintf(OF, "%%%%BoundingBox:         \n");
  162.     fprintf(OF, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
  163.  
  164.     fprintf(OF, "%%%%Title: PLplot Graph\n");
  165.     fprintf(OF, "%%%%Creator: PLplot Version %s\n", PLPLOT_VERSION);
  166.     fprintf(OF, "%%%%CreationDate: %s\n", ps_getdate());
  167.     fprintf(OF, "%%%%Pages: (atend)\n");
  168.     fprintf(OF, "%%%%EndComments\n\n");
  169.  
  170. /* Definitions */
  171. /* Save VM state */
  172.  
  173.     fprintf(OF, "/PSSave save def\n");
  174.  
  175. /* Define a dictionary and start using it */
  176.  
  177.     fprintf(OF, "/PSDict 200 dict def\n");
  178.     fprintf(OF, "PSDict begin\n");
  179.  
  180.     fprintf(OF, "/@restore /restore load def\n");
  181.     fprintf(OF, "/restore\n");
  182.     fprintf(OF, "   {vmstatus pop\n");
  183.     fprintf(OF, "    dup @VMused lt {pop @VMused} if\n");
  184.     fprintf(OF, "    exch pop exch @restore /@VMused exch def\n");
  185.     fprintf(OF, "   } def\n");
  186.     fprintf(OF, "/@pri\n");
  187.     fprintf(OF, "   {\n");
  188.     fprintf(OF, "    ( ) print\n");
  189.     fprintf(OF, "    (                                       ) cvs print\n");
  190.     fprintf(OF, "   } def\n");
  191.  
  192. /* n @copies - */
  193.  
  194.     fprintf(OF, "/@copies\n");
  195.     fprintf(OF, "   {\n");
  196.     fprintf(OF, "    /#copies exch def\n");
  197.     fprintf(OF, "   } def\n");
  198.  
  199. /* - @start -  -- start everything */
  200.  
  201.     fprintf(OF, "/@start\n");
  202.     fprintf(OF, "   {\n");
  203.     fprintf(OF, "    vmstatus pop /@VMused exch def pop\n");
  204.     fprintf(OF, "   } def\n");
  205.  
  206. /* - @end -  -- finished */
  207.  
  208.     fprintf(OF, "/@end\n");
  209.     fprintf(OF, "   {flush\n");
  210.     fprintf(OF, "    end\n");
  211.     fprintf(OF, "    PSSave restore\n");
  212.     fprintf(OF, "   } def\n");
  213.  
  214. /* bop -  -- begin a new page */
  215. /* Only fill background if we are using color and if the bg isn't white */
  216.  
  217.     fprintf(OF, "/bop\n");
  218.     fprintf(OF, "   {\n");
  219.     fprintf(OF, "    /SaveImage save def\n");
  220.     fprintf(OF, "   } def\n");
  221.  
  222. /* - eop -  -- end a page */
  223.  
  224.     fprintf(OF, "/eop\n");
  225.     fprintf(OF, "   {\n");
  226.     fprintf(OF, "    showpage\n");
  227.     fprintf(OF, "    SaveImage restore\n");
  228.     fprintf(OF, "   } def\n");
  229.  
  230. /* Set line parameters */
  231.  
  232.     fprintf(OF, "/@line\n");
  233.     fprintf(OF, "   {0 setlinecap\n");
  234.     fprintf(OF, "    0 setlinejoin\n");
  235.     fprintf(OF, "    1 setmiterlimit\n");
  236.     fprintf(OF, "   } def\n");
  237.  
  238. /* d @hsize -  horizontal clipping dimension */
  239.  
  240.     fprintf(OF, "/@hsize   {/hs exch def} def\n");
  241.     fprintf(OF, "/@vsize   {/vs exch def} def\n");
  242.  
  243. /* d @hoffset - shift for the plots */
  244.  
  245.     fprintf(OF, "/@hoffset {/ho exch def} def\n");
  246.     fprintf(OF, "/@voffset {/vo exch def} def\n");
  247.  
  248. /* Set line width */
  249.  
  250.     fprintf(OF, "/lw %d def\n", (int) (
  251.     (pls->width < MIN_WIDTH) ? DEF_WIDTH :
  252.     (pls->width > MAX_WIDTH) ? MAX_WIDTH : pls->width));
  253.  
  254. /* Setup user specified offsets, scales, sizes for clipping */
  255.  
  256.     fprintf(OF, "/@SetPlot\n");
  257.     fprintf(OF, "   {\n");
  258.     fprintf(OF, "    ho vo translate\n");
  259.     fprintf(OF, "    XScale YScale scale\n");
  260.     fprintf(OF, "    lw setlinewidth\n");
  261.     fprintf(OF, "   } def\n");
  262.  
  263. /* Setup x & y scales */
  264.  
  265.     fprintf(OF, "/XScale\n");
  266.     fprintf(OF, "   {hs %d div} def\n", YPSSIZE);
  267.     fprintf(OF, "/YScale\n");
  268.     fprintf(OF, "   {vs %d div} def\n", XPSSIZE);
  269.  
  270. /* Macro definitions of common instructions, to keep output small */
  271.  
  272.     fprintf(OF, "/M {moveto} def\n");
  273.     fprintf(OF, "/D {lineto} def\n");
  274.     fprintf(OF, "/S {stroke} def\n");
  275.     fprintf(OF, "/Z {stroke newpath} def\n");
  276.     fprintf(OF, "/F {fill} def\n");
  277.     fprintf(OF, "/C {setrgbcolor} def\n");
  278.     fprintf(OF, "/G {setgray} def\n");
  279.     fprintf(OF, "/W {setlinewidth} def\n");
  280.     fprintf(OF, "/B {Z %d %d M %d %d D %d %d D %d %d D %d %d closepath} def\n",
  281.         XMIN, YMIN, XMIN, YMAX, XMAX, YMAX, XMAX, YMIN, XMIN, YMIN);
  282.  
  283. /* End of dictionary definition */
  284.  
  285.     fprintf(OF, "end\n\n");
  286.  
  287. /* Set up the plots */
  288.  
  289.     fprintf(OF, "PSDict begin\n");
  290.     fprintf(OF, "@start\n");
  291.     fprintf(OF, "%d @copies\n", COPIES);
  292.     fprintf(OF, "@line\n");
  293.     fprintf(OF, "%d @hsize\n", YSIZE);
  294.     fprintf(OF, "%d @vsize\n", XSIZE);
  295.     fprintf(OF, "%d @hoffset\n", YOFFSET);
  296.     fprintf(OF, "%d @voffset\n", XOFFSET);
  297.  
  298.     fprintf(OF, "@SetPlot\n\n");
  299. }
  300.  
  301. /*--------------------------------------------------------------------------*\
  302.  * plD_line_ps()
  303.  *
  304.  * Draw a line in the current color from (x1,y1) to (x2,y2).
  305. \*--------------------------------------------------------------------------*/
  306.  
  307. void
  308. plD_line_ps(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
  309. {
  310.     PSDev *dev = (PSDev *) pls->dev;
  311.     int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
  312.  
  313. /* Rotate by 90 degrees */
  314.  
  315. /*    plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1);
  316.     plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2);*/
  317.  
  318.     if (x1 == dev->xold && y1 == dev->yold && dev->ptcnt < 40) {
  319.     if (pls->linepos + 12 > LINELENGTH) {
  320.         putc('\n', OF);
  321.         pls->linepos = 0;
  322.     }
  323.     else
  324.         putc(' ', OF);
  325. /* If user changed line width TELL the poor printer also! */        
  326.         if (pls->width != plsc->width)
  327.          { sprintf(outbuf," %d W ", (int) plsc->width);
  328.            pls->width=plsc->width;
  329.            pls->linepos += 5;
  330.          }
  331.     sprintf(outbuf, "%d %d D", x2, y2);
  332.     dev->ptcnt++;
  333.     pls->linepos += 12;
  334.     }
  335.     else {
  336.     fprintf(OF, " Z\n");
  337.     pls->linepos = 0;
  338.  
  339. /* If user changed line width TELL the poor printer also! */        
  340.         if (pls->width != plsc->width)
  341.          { sprintf(outbuf," %d W ", (int) plsc->width);
  342.            pls->width=plsc->width;
  343.            pls->linepos += 5;
  344.          }
  345.  
  346.     sprintf(outbuf, "%d %d M %d %d D", x1, y1, x2, y2);
  347.     dev->llx = MIN(dev->llx, x1);
  348.     dev->lly = MIN(dev->lly, y1);
  349.     dev->urx = MAX(dev->urx, x1);
  350.     dev->ury = MAX(dev->ury, y1);
  351.     dev->ptcnt = 1;
  352.     pls->linepos += 24;
  353.     }
  354.     dev->llx = MIN(dev->llx, x2);
  355.     dev->lly = MIN(dev->lly, y2);
  356.     dev->urx = MAX(dev->urx, x2);
  357.     dev->ury = MAX(dev->ury, y2);
  358.  
  359.     fprintf(OF, "%s", outbuf);
  360.     pls->bytecnt += 1 + strlen(outbuf);
  361.     dev->xold = x2;
  362.     dev->yold = y2;
  363. }
  364.  
  365. /*--------------------------------------------------------------------------*\
  366.  * plD_polyline_ps()
  367.  *
  368.  * Draw a polyline in the current color.
  369. \*--------------------------------------------------------------------------*/
  370.  
  371. void
  372. plD_polyline_ps(PLStream *pls, short *xa, short *ya, PLINT npts)
  373. {
  374.     PLINT i;
  375.  
  376.     for (i = 0; i < npts - 1; i++)
  377.     plD_line_ps(pls, xa[i], ya[i], xa[i + 1], ya[i + 1]);
  378. }
  379.  
  380. /*--------------------------------------------------------------------------*\
  381.  * plD_eop_ps()
  382.  *
  383.  * End of page.
  384. \*--------------------------------------------------------------------------*/
  385.  
  386. void
  387. plD_eop_ps(PLStream *pls)
  388. {
  389.     fprintf(OF, " S\neop\n");
  390. }
  391.  
  392. /*--------------------------------------------------------------------------*\
  393.  * plD_bop_ps()
  394.  *
  395.  * Set up for the next page.
  396. \*--------------------------------------------------------------------------*/
  397.  
  398. void
  399. plD_bop_ps(PLStream *pls)
  400. {
  401.     PSDev *dev = (PSDev *) pls->dev;
  402.  
  403.     dev->xold = UNDEFINED;
  404.     dev->yold = UNDEFINED;
  405.  
  406.     pls->page++;
  407.     fprintf(OF, "%%%%Page: %d %d\n", (int) pls->page, (int) pls->page);
  408.     fprintf(OF, "bop\n");
  409.     if (pls->color) {
  410.     float r, g, b;
  411.     if (pls->cmap0[0].r != 0xFF ||
  412.         pls->cmap0[0].g != 0xFF ||
  413.         pls->cmap0[0].b != 0xFF ) {
  414.  
  415.         r = ((float) pls->cmap0[0].r) / 255.;
  416.         g = ((float) pls->cmap0[0].g) / 255.;
  417.         b = ((float) pls->cmap0[0].b) / 255.;
  418.  
  419.         fprintf(OF, "B %.4f %.4f %.4f C F\n", r, g, b);
  420.     }
  421.     }
  422.     pls->linepos = 0;
  423.  
  424. /* This ensures the color is set correctly at the beginning of each page */
  425.  
  426.     plD_state_ps(pls, PLSTATE_COLOR0);
  427. }
  428.  
  429. /*--------------------------------------------------------------------------*\
  430.  * plD_tidy_ps()
  431.  *
  432.  * Close graphics file or otherwise clean up.
  433. \*--------------------------------------------------------------------------*/
  434.  
  435. void
  436. plD_tidy_ps(PLStream *pls)
  437. {
  438.     PSDev *dev = (PSDev *) pls->dev;
  439.  
  440.     fprintf(OF, "\n%%%%Trailer\n");
  441.  
  442.     dev->llx /= ENLARGE;
  443.     dev->lly /= ENLARGE;
  444.     dev->urx /= ENLARGE;
  445.     dev->ury /= ENLARGE;
  446.     dev->llx += XOFFSET;
  447.     dev->lly += YOFFSET;
  448.     dev->urx += XOFFSET;
  449.     dev->ury += YOFFSET;
  450.  
  451. /* changed for correct Bounding boundaries Jan Thorbecke  okt 1993*/
  452. /* occurs from the integer truncation -- postscript uses fp arithmetic */
  453.  
  454.     dev->urx += 1;
  455.     dev->ury += 1;
  456.  
  457.     fprintf(OF, "%%%%Pages: %d\n", (int) pls->page);
  458.     fprintf(OF, "@end\n");
  459.  
  460. /* Backtrack to write the BoundingBox at the beginning */
  461. /* Some applications don't like it atend */
  462.  
  463.     rewind(OF);
  464.     fprintf(OF, "%%!PS-Adobe-2.0 EPSF-2.0\n");
  465.     fprintf(OF, "%%%%BoundingBox: %d %d %d %d\n",
  466.         dev->llx, dev->lly, dev->urx, dev->ury);
  467.     fclose(OF);
  468. }
  469.  
  470. /*--------------------------------------------------------------------------*\
  471.  * plD_state_ps()
  472.  *
  473.  * Handle change in PLStream state (color, pen width, fill attribute, etc).
  474. \*--------------------------------------------------------------------------*/
  475.  
  476. void 
  477. plD_state_ps(PLStream *pls, PLINT op)
  478. {
  479.     PSDev *dev = (PSDev *) pls->dev;
  480.  
  481.     switch (op) {
  482.  
  483.     case PLSTATE_WIDTH:{
  484.     int width = 
  485.         (pls->width < MIN_WIDTH) ? DEF_WIDTH :
  486.         (pls->width > MAX_WIDTH) ? MAX_WIDTH : pls->width;
  487.  
  488.     fprintf(OF, " S\n%d W", width);
  489.  
  490.     dev->xold = UNDEFINED;
  491.     dev->yold = UNDEFINED;
  492.     break;
  493.     }
  494.     case PLSTATE_COLOR0:
  495.      if (! pls->color) {
  496.         fprintf(OF, " S\n%.4f G", (pls->icol0 ? 0.0 : 1.0));
  497.         break;
  498.     }
  499.     /* else fallthrough */
  500.     case PLSTATE_COLOR1:
  501.     if (pls->color) {
  502.         float r = ((float) pls->curcolor.r) / 255.0;
  503.         float g = ((float) pls->curcolor.g) / 255.0;
  504.         float b = ((float) pls->curcolor.b) / 255.0;
  505.  
  506.         fprintf(OF, " S\n%.4f %.4f %.4f C", r, g, b);
  507.     }
  508.     else {
  509.         float r = ((float) pls->curcolor.r) / 255.0;
  510.         fprintf(OF, " S\n%.4f G", 1.0 - r);
  511.     }
  512.     break;
  513.     }
  514.  
  515. /* Reinitialize current point location. */
  516.  
  517.     if (dev->xold != UNDEFINED && dev->yold != UNDEFINED) {
  518.     fprintf(OF, " %d %d M \n", (int)dev->xold, (int)dev->yold);
  519.     }
  520. }
  521.  
  522. /*--------------------------------------------------------------------------*\
  523.  * plD_esc_ps()
  524.  *
  525.  * Escape function.
  526. \*--------------------------------------------------------------------------*/
  527.  
  528. void
  529. plD_esc_ps(PLStream *pls, PLINT op, void *ptr)
  530. {
  531.     switch (op) {
  532.       case PLESC_FILL:
  533.     fill_polygon(pls);
  534.     break;
  535.     }
  536. }
  537.  
  538. /*--------------------------------------------------------------------------*\
  539.  * fill_polygon()
  540.  *
  541.  * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
  542.  * Only solid color fill supported.
  543. \*--------------------------------------------------------------------------*/
  544.  
  545. static void
  546. fill_polygon(PLStream *pls)
  547. {
  548.     PSDev *dev = (PSDev *) pls->dev;
  549.     PLINT n, ix = 0, iy = 0;
  550.     int x, y;
  551.  
  552.     fprintf(OF, " Z\n");
  553.  
  554.     for (n = 0; n < pls->dev_npts; n++) {
  555.     x = pls->dev_x[ix++];
  556.     y = pls->dev_y[iy++];
  557.  
  558. /* Rotate by 90 degrees */
  559.  
  560.     plRotPhy(1, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x, &y);
  561.  
  562. /* First time through start with a x y moveto */
  563.  
  564.     if (n == 0) {
  565.         sprintf(outbuf, "%d %d M", x, y);
  566.         dev->llx = MIN(dev->llx, x);
  567.         dev->lly = MIN(dev->lly, y);
  568.         dev->urx = MAX(dev->urx, x);
  569.         dev->ury = MAX(dev->ury, y);
  570.         fprintf(OF, "%s", outbuf);
  571.         pls->bytecnt += strlen(outbuf);
  572.         continue;
  573.     }
  574.  
  575.     if (pls->linepos + 21 > LINELENGTH) {
  576.         putc('\n', OF);
  577.         pls->linepos = 0;
  578.     }
  579.     else
  580.         putc(' ', OF);
  581.  
  582.     pls->bytecnt++;
  583.  
  584.     sprintf(outbuf, "%d %d D", x, y);
  585.     dev->llx = MIN(dev->llx, x);
  586.     dev->lly = MIN(dev->lly, y);
  587.     dev->urx = MAX(dev->urx, x);
  588.     dev->ury = MAX(dev->ury, y);
  589.  
  590.     fprintf(OF, "%s", outbuf);
  591.     pls->bytecnt += strlen(outbuf);
  592.     pls->linepos += 21;
  593.     }
  594.     dev->xold = UNDEFINED;
  595.     dev->yold = UNDEFINED;
  596.     fprintf(OF, " F ");
  597. }
  598.  
  599. /*--------------------------------------------------------------------------*\
  600.  * ps_getdate()
  601.  *
  602.  * Get the date and time
  603. \*--------------------------------------------------------------------------*/
  604.  
  605. static char *
  606. ps_getdate(void)
  607. {
  608.     int len;
  609.     time_t t;
  610.     char *p;
  611.  
  612.     t = time((time_t *) 0);
  613.     p = ctime(&t);
  614.     len = strlen(p);
  615.     *(p + len - 1) = '\0';    /* zap the newline character */
  616.     return p;
  617. }
  618.  
  619. #else
  620. int 
  621. pldummy_ps()
  622. {
  623.     return 0;
  624. }
  625.  
  626. #endif                /* PLD_ps */
  627.